import re
import os
import csv
import datetime

__all__ = ['MarketFetcher']
from ..fetcher import *
class Market(Fetcher):

    file_re = re.compile('''^
        (?P<export_region> [^-]+) -
        (?P<export_item>   .+   ) -
        (?P<export_year>   \d{4}) \.
        (?P<export_month>  \d{2}) \.
        (?P<export_day>    \d{2}) \s+
        (?P<export_hour>   \d{2})
        (?P<export_minute> \d{2})
        (?P<export_second> \d{2})
        \.txt$''', re.X + re.I)

    def read(self, fields, *, filepath, delimiter = ',', quotechar = '\"', encoding = 'windows-1251'):

        matches = self.file_re.search(os.path.basename(filepath))
        if not matches: raise Error("Can not fetch from non-market file '"+filepath+"'.")
        else: matches = matches.groupdict()

        reader = csv.DictReader(
                open(filepath,
                newline="", encoding=encoding, ),
                delimiter=delimiter, quotechar=quotechar, )

        #@TODO: make it as a separate method, maybe in base class
        for row in reader:
            res = dict(row)

            for name in matches: res[name] = matches[name]#@todo: requested names only, или даже в общем цикле (for in self.fields) и брать, тоьлко сверять по наличию в row/matches
            res['export_datetime'] = datetime.datetime(#@todo: only if requested, and of appropriate type (datetime/int/long/float)
                int(matches['export_year']),
                int(matches['export_month']),
                int(matches['export_day']),
                int(matches['export_hour']),
                int(matches['export_minute']),
                int(matches['export_second']))

            yield res

    def cast(self, caster, value):
        if type(value) == caster: return value
        if value in (None, "", "null", "Null", "NULL"): return None
        if caster == float: return caster(value.replace("\xA0", "").replace(",", "."))
        if caster == int  : return caster(value.replace("\xA0", ""))
        if caster == bool : return caster(value in ("True", "true"))#@TODO: raise if value is not in true, nor in false list
        if caster == str  : return caster(value)
        #!!!todo: datetimestamp
        raise TypeError("Fetcher does not support casters of type "+repr(type(caster))+".")
